<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Title</title></head><body><div class="cl-preview-section"><h1 id="flutter主流状态管理框架provider、bloc、redux对比">Flutter主流状态管理框架provider、bloc、redux对比</h1>
</div><div class="cl-preview-section"><p><img src="https://o.devio.org/images/fa/res/provider-bloc-redux.png" alt="provider-bloc-redux"></p>
</div><div class="cl-preview-section"><ul>
<li>为什么需要状态管理</li>
<li>provider</li>
<li>bloc</li>
<li>redux</li>
<li>对比</li>
<li>总结</li>
</ul>
</div><div class="cl-preview-section"><h2 id="为什么需要状态管理">为什么需要状态管理</h2>
</div><div class="cl-preview-section"><p>在了解和进行Flutter状态管理框架对比之前呢，我们先来问自己一个问题：为什么需要状态管理？</p>
</div><div class="cl-preview-section"><p>如果我们的应用足够简单，Flutter作为一个声明式框架，我们或许只需要将数据映射成视图就可以了。我们可能并不需要状态管理，就像下面这张图：</p>
</div><div class="cl-preview-section"><p><img src="https://o.devio.org/images/fa/res/flutter-widget-tree.png" alt="flutter-widget-tree"></p>
</div><div class="cl-preview-section"><p>但是随着功能的增加，我们的应用程序将会有几十个甚至上百个状态。这个时候我们的应用将会变成这样：</p>
</div><div class="cl-preview-section"><p><img src="https://o.devio.org/images/fa/res/flutter-wiget-state-tree.png" alt="flutter-wiget-state-tree"></p>
</div><div class="cl-preview-section"><p>在这种情况下我们很难再清楚的测试维护我们的状态，因为它看上去实在是太复杂了！而且还会有多个页面共享同一个状态。这个时候如果想在详情页改变一个模型的状态比如点赞收藏，在返回到列表时能够及时更新这个状态，在默认情况下是很难实现的。</p>
</div><div class="cl-preview-section"><p>整个问题出在Flutter为我们提供的状态管理方式：StatefulWidget。因为State 属于某一个特定的 Widget，在多个 Widget 之间进行交流的时候，虽然你可以使用callback 解决，但是当嵌套足够深的话，那么将进入callback传递的地狱。<br>
这时候，我们便迫切的需要一个架构来帮助我们理清这些关系，并且轻松实现状态的管理和共享，这个时候我们就需要用到状态管理框了。</p>
</div><div class="cl-preview-section"><h2 id="provider">provider</h2>
</div><div class="cl-preview-section"><p>provider是基于InheritedWidget的包装，通过使用provider而不是手动编写InheritedWidget就可以实现页面和其子页面间的数据共享。</p>
</div><div class="cl-preview-section"><blockquote>
<p>provider是<a href="https://flutter.dev/docs/development/packages-and-plugins/favorites">Flutter Favorite</a>中的插件之一，也是目前<br>
Flutter官方推荐和使用最多的状态管理框架。</p>
</blockquote>
</div><div class="cl-preview-section"><p>provider提供的主要功能有：</p>
</div><div class="cl-preview-section"><ul>
<li>简化的资源分配与处置</li>
<li>懒加载</li>
<li>相较于每次创建一个新类，大大减少模板代码量</li>
<li>对开发者工具更为友好</li>
<li>更通用的消费 InheritedWidget 的方式(见 Provider.of/Consumer/Selector )</li>
<li>提升类的可伸缩性，整体的监听架构(listening mechanism)时间复杂度以指数级增长(如ChangeNotifier， 其复杂度为O(N²))</li>
</ul>
</div><div class="cl-preview-section"><blockquote>
<p>建议之前还没接触过<code>provider</code>小伙伴，可以通过Flutter官网的这个<a href="https://flutter.cn/docs/development/data-and-backend/state-mgmt/simple">simple</a>以及官方文<a href="https://github.com/rrousselGit/provider/blob/master/resources/translations/zh-CN/README.md">API说明</a>来练习下对provider的使用，以方便后面课程的学习。</p>
</blockquote>
</div><div class="cl-preview-section"><h2 id="bloc">bloc</h2>
</div><div class="cl-preview-section"><p>BLoC全称（Business Logic Component)是谷歌提出的一种设计模式，利用流的方式实现界面的异步渲染和重绘，我们可以非常快速的通过BLoC实现业务与界面的分离。</p>
</div><div class="cl-preview-section"><blockquote>
<p>BLoC只是一种设计模式，不包含任何代码，所以要在Flutter中实现BLoC设计模式需要借助<a href="https://pub.dev/packages/flutter_bloc">flutter_bloc</a>这个库来完成。</p>
</blockquote>
</div><div class="cl-preview-section"><p><code>flutter_bloc</code>是一个可预测的状态管理库，可帮助我们实现BLoC（业务逻辑组件）设计模式。</p>
</div><div class="cl-preview-section"><p>BLoC设计模式有助于将UI与业务逻辑分开。遵循BLoC模式有利于项目的可测试性和可重用性。在BLoC中有个非常重要的概念：<code>Cubit</code>。</p>
</div><div class="cl-preview-section"><h3 id="cubit">Cubit</h3>
</div><div class="cl-preview-section"><p><img src="https://o.devio.org/images/fa/res/cubit_architecture_full.png" alt="cubit_architecture_full"></p>
</div><div class="cl-preview-section"><p>Cubit是Bloc的基础（也可以说是Bloc基于Cubit）。Cubit是一种特殊类型Stream，可以扩展以及管理任何类型的状态。Cubit需要一个初始状态，该状态将是emit被调用之前的状态。<code>cubit</code>的当前状态可以通过<code>state</code>来获取，并且可以通过<code>emit</code><br>
来生成一个新的<code>state</code>来达到更新<code>cubit</code>状态的目的：</p>
</div><div class="cl-preview-section"><p><img src="https://o.devio.org/images/fa/res/cubit_flow.png" alt="cubit_flow"></p>
</div><div class="cl-preview-section"><p>cubit状态更改始于预定义的函数调用，这些函数可以使用该emit方法输出新状态。onChange在每个状态更改时调用，并包含当前状态和下一个状态。</p>
</div><div class="cl-preview-section"><blockquote>
<p>对<code>bloc</code>设计模式感兴趣的小伙伴可以通过flutter_bloc的<a href="https://github.com/felangel/bloc/tree/master/packages/flutter_bloc/example">example</a>获取具体的用例。</p>
</blockquote>
</div><div class="cl-preview-section"><h2 id="redux">Redux</h2>
</div><div class="cl-preview-section"><p>接下来我们说说Redux，说到Redux 前端小伙伴一定都不陌生，Redux 是 JavaScript 状态容器，提供可预测化的状态管理，可以让你构建一致化的应用，运行于不同的环境（客户端、服务器、原生应用），并且易于测试。</p>
</div><div class="cl-preview-section"><p>Redux最为关键的就是它的数据流了：</p>
</div><div class="cl-preview-section"><p><img src="https://www.devio.org/io/githubapp/redux-flow.png" alt="redux数据流"></p>
</div><div class="cl-preview-section"><p>redux数据流：</p>
</div><div class="cl-preview-section"><ul>
<li>用户（操作View）发出Action，发出方式就用到了dispatch方法；</li>
<li>然后，Store自动调用Reducer，并且传入两个参数(当前State和收到的Action)，Reducer会返回新的State，如果有Middleware，Store会将当前State和收到的Action传递给Middleware，Middleware会调用Reducer 然后返回新的State；</li>
<li>State一旦有变化，Store就会调用监听函数，来更新View；</li>
</ul>
</div><div class="cl-preview-section"><p>到这儿为止，一次用户交互流程结束。可以看到，在整个流程中数据都是单向流动的。</p>
</div><div class="cl-preview-section"><blockquote>
<p>与其说Redux是一个框架倒不如说Redux是一个设计思想，Redux在不同语言和框架中有不同的实现，比如在react-native可以借助中有<a href="https://www.imooc.com/article/281446">react-redux</a>来实现Redux。在Flutter中如果想使用Redux可以借助<a href="https://pub.dev/packages/flutter_redux">flutter_redux</a>来完成。</p>
</blockquote>
</div><div class="cl-preview-section"><h2 id="总结">总结</h2>
</div><div class="cl-preview-section"><div class="table-wrapper"><table>
<thead>
<tr>
<th>框架/方案</th>
<th>优点</th>
<th>缺点</th>
<th>使用建议</th>
</tr>
</thead>
<tbody>
<tr>
<td>setState</td>
<td>无需引入依赖、使用简单</td>
<td>不支持页面间数据共享</td>
<td>适用于较小规模项目的状态基础管理方法</td>
</tr>
<tr>
<td>provider</td>
<td>基于InheritedWidget、简洁易用、Flutter官方推荐</td>
<td>只能实现页面和其子页面间的状态共享</td>
<td>中大型项目首选方案</td>
</tr>
<tr>
<td>bloc</td>
<td>能够很好地实现业务逻辑的复用以及视图与业务逻辑的分离</td>
<td>使用上结构相对复杂</td>
<td>在Flutter中除provider外，另一个不错的状态管理方案</td>
</tr>
<tr>
<td>redux</td>
<td>受众广、其它语言或框架也都有实现</td>
<td>概念较多比较难理解</td>
<td>如果之前使用过Redux并且不想引入provider的情况下</td>
</tr>
</tbody>
</table>
</div></div> <h1 style="color: red">认准一手，获取完整资料<br>QQ3195303913<br>微信wxywd8<br><br><br><br>高价回收正版课</h1></body></html>